package com.yonyou.brigade.rtpnr.core;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.yonyou.brigade.basic_init.service.IDeveloperService;
import com.yonyou.brigade.rtpnr.model.BriRtpnrpri;
import com.yonyou.brigade.rtpnr.model.EntInfo;
import com.yonyou.brigade.rtpnr.service.IBriRtpnrpriService;
import com.yonyou.brigade.rtpnr.service.IEntInfoService;
import com.yonyou.brigade.rtpnr.util.Encode;
import com.yonyou.brigade.rtpnr.util.XMLStringUtil;
import com.yonyou.brigade.rtpnr.util.XMLUtil;
import com.yonyou.brigade.util.mail.MailSenderUtil;
import com.yonyou.ybzboot.starter.common.exception.BaseException;
import com.yonyou.ybzboot.starter.common.thread.ThreadPoolExecutorFactory;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.ParserConfigurationException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
@Slf4j
public class CXFInvokeClient implements CommandLineRunner {

    private String baseUrl;

    private String methodName;

    private String TMCID;

    private Client client;

    //中航易购私有化部署
    private Map<String, Client> ClientMap = new HashMap<>();
    private Map<String, String> TMCIDMap = new HashMap<>();

    @Autowired
    @Qualifier("entInfoServiceImpl")
    private IEntInfoService entInfoService;

    @Autowired
    @Qualifier("briRtpnrpriServiceImpl")
    private IBriRtpnrpriService briRtpnrpriService;

    @Autowired
    private IDeveloperService developerService;

    public String callService(String tenant, String orgpk, String requestXml, String filterXml) {
        try {
            EntInfo entInfo = entInfoService.getEntInfoByTenantOrg(tenant, orgpk);
            if (entInfo == null) {
                throw new BaseException(-100, "该组织并未开通中航易购");
            }

            String clientKey = tenant.concat(orgpk);
            if (ClientMap != null && ClientMap.containsKey(clientKey)) {
                String flag = clientKey;
                Object[] objects = ClientMap.get(flag).invoke(methodName, getIdentityXmlString(entInfo.getEntID(), entInfo.getPubKey(), requestXml, TMCIDMap.get(flag)), requestXml, filterXml);
                if (objects != null && objects.length > 0) {
                    Object object = objects[0];
                    return object.toString();
                } else {
                    throw new BaseException(-100, "webservice返回的值为空");
                }
            } else {
                ThreadPoolExecutorFactory.getParallelPoolExecutor().execute(() -> {
                    log.info("中航易购Client恢复机制开始");
                    JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
                    //默认连接初始化失败重新初始化
                    if (client == null) {
                        try {
                            client = dcf.createClient(baseUrl);
                            String msg = "友商旅默认连接恢复，地址" + baseUrl;
                            log.error(msg);
                            MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "友商旅默认连接恢复", msg);
                        } catch (Exception e) {
                            String msg = "友商旅Client初始化异常，地址" + baseUrl + "，异常信息{}\r\n" + Arrays.toString(e.getStackTrace());
                            log.error(msg);
                        }
                    }
                    Wrapper<BriRtpnrpri> wrapper = new EntityWrapper<>();
                    wrapper.eq(BriRtpnrpri.TENANT, tenant);
                    wrapper.eq(BriRtpnrpri.ORGPK, orgpk);
                    List<BriRtpnrpri> briRtpnrpriList = briRtpnrpriService.selectList(wrapper);
                    BriRtpnrpri rtpnrPri = new BriRtpnrpri();
                    String priUrl = "";
                    if (!CollectionUtils.isEmpty(briRtpnrpriList)) {
                        rtpnrPri = briRtpnrpriList.get(0);
                        priUrl = rtpnrPri.getRtpnrPriUrl();
                    }
                    try {
                        if (!CollectionUtils.isEmpty(briRtpnrpriList)) {

                            Client client = dcf.createClient(priUrl);
                            String msg = "友商旅Client初始化成功，地址:" + priUrl;
                            log.error(msg);
                            ClientMap.put(clientKey, client);
                            TMCIDMap.put(clientKey, rtpnrPri.getTmcid());
                            MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "友商旅服务恢复提醒", msg);
                        }
                    } catch (Exception e) {
                        log.error("友商旅Client初始化异常，地址{}，异常信息{}", priUrl, e.getMessage());
                    }
                });

                Object[] objects = client.invoke(methodName, getIdentityXmlString(entInfo.getEntID(), entInfo.getPubKey(), requestXml, null), requestXml, filterXml);
                if (objects != null && objects.length > 0) {
                    Object object = objects[0];
                    return object.toString();
                } else {
                    throw new BaseException(-100, "webservice返回的值为空");
                }
            }
        } catch (Exception e) {
            throw new BaseException(-100, e.getMessage());
        }
    }

    private String getIdentityXmlString(String entId, String pubKey, String requestXmlString, String tmcid) {
//        String entId = "556";
//        String pubKey = "c6f67653b1f54ad19df9778873f43f75";
        try {
            Document document = XMLUtil.newDocument();
            Element e_Identity_1_0 = document.createElement("Identity_1_0");
            Element e_TMCID = document.createElement("TMCID");
            Element e_EntID = document.createElement("EntID");
            Element e_VerCode = document.createElement("VerCode");
            String sVerCode = null;
            if (tmcid != null) {
                sVerCode = Encode.getMD5(tmcid + entId + requestXmlString + pubKey);
                e_TMCID.setTextContent(tmcid);
            } else {
                sVerCode = Encode.getMD5(TMCID + entId + requestXmlString + pubKey);
                e_TMCID.setTextContent(TMCID);
            }

            e_EntID.setTextContent(entId);
            e_VerCode.setTextContent(sVerCode);

            e_Identity_1_0.appendChild(e_TMCID);
            e_Identity_1_0.appendChild(e_EntID);
            e_Identity_1_0.appendChild(e_VerCode);
            document.appendChild(e_Identity_1_0);

            return XMLStringUtil.doc2String(document);

        } catch (ParserConfigurationException e) {
            throw new BaseException(-100, e.getMessage());
        }

    }

    public String addRtpnrClien(String tenant, String orgpk, String rtpnrUrl, String tmcid) {
        String clientStr = tenant.concat(orgpk);
        //创建新的中航易购私有化部署client
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(rtpnrUrl);
        ClientMap.put(clientStr, client);
        TMCIDMap.put(clientStr, tmcid);
        //数据入库
        BriRtpnrpri rp = new BriRtpnrpri();
        rp.setTenant(tenant);
        rp.setOrgpk(orgpk);
        rp.setRtpnrPriUrl(rtpnrUrl);
        rp.setTmcid(tmcid);

        Wrapper<BriRtpnrpri> wrapper = new EntityWrapper<>();
        wrapper.eq(BriRtpnrpri.TENANT, tenant);
        wrapper.eq(BriRtpnrpri.ORGPK, orgpk);
        BriRtpnrpri briRtpnrpri = briRtpnrpriService.selectOne(wrapper);
        if (briRtpnrpri == null) {
            boolean b = briRtpnrpriService.insert(rp);
            if (b) {
                return "success";
            } else {
                return "fail";
            }
        } else {
            return "success";
        }
    }

    /**
     * 友商旅服务启动初始化客户端
     *
     * @param args []
     * @throws Exception ""
     */
    @Override
    public void run(String... args) throws Exception {
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        List<BriRtpnrpri> briRtpnrpris = briRtpnrpriService.selectList(null);
        Map<String, Client> clientMapTemp = new HashMap<>();
        // 私有化部署连接初始化
        if (briRtpnrpris != null) {
            for (BriRtpnrpri rtpnrpris : briRtpnrpris) {
                String clientStr = rtpnrpris.getTenant() + rtpnrpris.getOrgpk();
                String rtpnrPriUrl = rtpnrpris.getRtpnrPriUrl();
                if (clientMapTemp.containsKey(rtpnrPriUrl)) {
                    ClientMap.put(clientStr, clientMapTemp.get(rtpnrPriUrl));
                    TMCIDMap.put(clientStr, rtpnrpris.getTmcid());
                } else {
                    try {
                        Client client = dcf.createClient(rtpnrPriUrl);
                        log.error("友商旅Client初始化成功，地址{}", rtpnrPriUrl);
                        ClientMap.put(clientStr, client);
                        clientMapTemp.put(rtpnrPriUrl, client);
                        TMCIDMap.put(clientStr, rtpnrpris.getTmcid());
                    } catch (Exception e) {
                        String msg = "友商旅Client初始化异常，地址" + rtpnrPriUrl + "，异常信息{}\r\n" + Arrays.toString(e.getStackTrace());
                        log.error(msg);
                        MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "友商旅初始化异常", msg);
                    }
                }
            }
        }
        // 默认连接初始化
        try {
            client = dcf.createClient(baseUrl);
            log.error("友商旅Client初始化成功，地址{}", baseUrl);
        } catch (Exception e) {
            String msg = "友商旅Client初始化异常，地址" + baseUrl + "，异常信息{}\r\n" + Arrays.toString(e.getStackTrace());
            log.error(msg);
            MailSenderUtil.sendCommonMail(developerService.listEmailByType("YY"), "友商旅初始化异常", msg);
        }
    }
}